(function() {
	var HZBank = this.HZBank || (this.HZBank = {});
	var Core = HZBank.Core = HZBank.Core || (this.HZBank.Core = {});
	var $ = this.$ || this.jQuery;

	var LOG_LEVEL = {
		DEBUG : 10,
		INFO : 20,
		ERROR : 30
	};

	Core.options = {
		logLevel : LOG_LEVEL.INFO
	};

	Core.extend = function(base, props) {
		var transfor = function(){};
		transfor.prototype = base.prototype;
		var child = new transfor();
		$.extend(child.prototype, props);
		if (!child.constructor) {
			child.constructor = function() {

			};
		}
		return child;
	};
	Core.logger = {
		info : function(msg, e) {
			if (Core.options.logLevel <= LOG_LEVEL.INFO) {
				//console.log(msg !== undefined ? msg : '', e !== undefined ? e : '');
			}
		},
		debug : function(msg, e) {
			if (Core.options.logLevel <= LOG_LEVEL.DEBUG) {
				//console.log(msg !== undefined ? msg : '', e !== undefined ? e : '');
			}
		},
		warn : function(msg, e) {
			if (Core.options.logLevel <= LOG_LEVEL.DEBUG) {
				//console.log(msg !== undefined ? msg : '', e !== undefined ? e : '');
			}
		},
		error : function(msg, e) {
			if (Core.options.logLevel <= LOG_LEVEL.ERROR) {
				//console.log(msg !== undefined ? msg : '', e !== undefined ? e : '');
			}
		}
	};
	// submit data for form
	
	/**
	 * AJAX请求
	 * 
	 * @param options {JSON}
	 *            errorHanlder 	: 错误数据处理方法
	 *            failed		: 请求成功但结果有错误的处理方法
	 */
	Core.ajax = function(options) {
		options = options || {};

		options = $.extend({
			type : 'POST'
		}, options);
		var error = options.error;
//		var deskError = options.deskError === undefined ? true : options.deskError;
//		options.error = function(jqXHR, textStatus, errorThrown) {
//			if (deskError) {
//				HZBank.Core.errorHandler.apply(this, [ jqXHR, textStatus, errorThrown, options ]);
//			}
//			if (error) {
//				error.apply(this, arguments);
//			}
//		};

		var success = options.success;
		Core.clearError(options);
		var errorHanlder = options.errorHanlder || Core.errorHandler;
		var serviceFun = options.serviceFun ||'';
		options.success = function(data, textStatus, jqXHR) {
			if (data.successed) {
				if (success) {
					success.apply(this, arguments);
				}
			} else {
				if (errorHanlder) {
					errorHanlder.apply(this, [ data, textStatus, jqXHR, options ]);
				}
				if($.isFunction(serviceFun)){
					serviceFun.apply(this, [ data, textStatus, jqXHR, options ]);
				}
				options.failed && options.failed.apply(this, arguments);
			}
		};

		return $.ajax(options);
	};
	/**
	 * AJAX JSON请求
	 * 
	 * @param options {JSON} 参考Core.ajax
	 */
	Core.ajaxJSON = function(options) {
		$.extend(options, {
			contentType : 'application/json; charset=UTF-8',
			dataType : 'JSON'
		});
		return Core.ajax(options);
	};
	/**
	 * AJAX Page请求
	 * 
	 * @param options {JSON} 参考jQuery.load
	 */
	Core.loadPage = function(opts) {
		$(opts.el).load(opts.url, opts.data, opts.success);
	};
	Core.open = function(options) {
		window.open(options.url);
	};
	/**
	 * 清理页面错误信息
	 * 
	 * @param options {JSON} 
	 * 				errorEl : 错误显示区域
	 */
	Core.clearError = function(options) {
		var $error = $(options.errorEl || "#error"),
			error = $error.find('ul.error-list').data('error');
		if (error) {
			var	$els = error.els;
			$els.removeClass('error');
			$els.tooltip('destroy');
		}
		$error.empty();
	};
	/**
	 * 清理页面错误信息
	 * 
	 * @param data 
	 * 				参考jQuery ajax 
	 * @param textStatus 
	 * 				参考jQuery ajax 
	 * @param jqXHR 
	 * 				参考jQuery ajax 
	 * @param options{JSON}
	 * 				errorEl : 错误显示区域
	 */
	Core.errorHandler = function(data, textStatus, jqXHR, options) {
		var callback = options.closeFun ||$.noop;
		var tip;
		if($.isFunction(HZBank.app.tip)){
			tip = new HZBank.app.tip(); 
		}
		//var $error = $(options.errorEl || "#error"),
		var config = {
				$element:$('body'),
				type:'dialog',  				 //弹出类型， 'tip','dialog',iframe
				position:'top',
				height:200,
				width:400,
				animate:'normal',			////出现方式  fade  normal
				closeButton:true,			//是否有关闭按钮，默认没有
				needbind:true,            //自己绑定事件 
				needmin:false,
				needscroll:true,
				partinput:true,
				needmask:true,
				callback:callback,
				endcallback:function(a,b,c){
					var h = c.config.content.outerHeight();
					if(h<80){
						c.cache.$tipContent.height(100);
						c.cache.$tipbody.height(130);
					}
				}
		};
			var $ul = $('<ul class="error-list">');
		//	$els = $();
		if (true){//$error.length !== 0) {
			//$error.empty();
			if (data.exceptionCode === 200) {
				var errorList = data.errors;
				if (errorList) {
					// used for clear error.
					for ( var i = 0; i < errorList.length; i++) {
						var item = errorList[i], $li = $('<li>'), $el = $('[name="' + item.element + '"]');
						var errorName = '';
						if($el.length > 0){
							//$els = $els.add($el);
							if ($el.is('select')) {
								$el = $el.parent('.ui-select');
								$el.addClass('error');
								$el.attr('title', item.message);
								errorName = $el.prev().html() || '选择项';
							} else if ($el.is('input')) {
								if($el.closest('.ui-unit-box,.yearBox').length > 0){
									$el = $el.parent('.ui-unit-box,.yearBox');
								}
								$el.addClass('error');
								$el.attr('title', item.message);
								errorName = $el.prev().html() || '输入项';
							}else if($el.is('textarea')){
								$el.addClass('error');
								$el.attr('title', item.message);
								errorName = $el.prev().html() || '输入项';
							}
							$el.unbind('click.serviceERR').bind('click.serviceERR',function(){
								$(this).removeClass('error')
							})
						}else{
							errorName = '后台业务异常';
						}
						var span = '<span><i class="icon-alert icons"></i></span>'+errorName + ' :  ' + item.message;
						$li.html(span);
						$ul.append($li);
					}
					var c = config;
					 c.content = $ul;
					 tip.init(c);
//					$els.tooltip({
//						position : {
//							my : 'left',
//							at : 'right'
//						},
//						tooltipClass : 'ui-hzbank-tooltip'
//					});
//					$ul.data('error', {
//						errorList : errorList,
//						els : $els
//					});
				}
			} else if(data.exceptionCode === 501) {
				
				var msg = data.exceptionMsg.split('|');
				for(var i=0;i<msg.length;i++){
					if(msg[i].length > 1){
						var $li = $('<li>');
						var code = msg[i].split(',');
						
						$li.html('[' + code[0] + '] ' + (code[1]==null?'':(code[1]=='null'?'':code[1])));
							$ul.append($li);
					}
					
				}
				var c = config;
				 c.content = $ul;
				 tip.init(c);
			} else {
				var msg = data.exceptionMsg;
				var $li = $('<li>');
				$li.html('[' + data.exceptionCode + '] ' + (msg==null?'':(msg=='null'?'':msg)));
				$ul.append($li);
				var c = config;
				 c.content = $ul;
				 c.height = 150;
				 c.width = 250;
				 tip.init(c);
			}
			//$error.hide();
			//$error.append($ul);
			return $ul
			//HZBank.showFail($error.html());
		}
	};
	//page cache in memory, shall we change it to local storage?
	Core.Cache = {
		data : {},
		callback : {},
		content : {},
		/*
		 * 获取缓存数据
		 * 
		 * @param key
		 * 
		 */
		getData : function(key) {
			return this.data[key];
		},
		/*
		 * 添加缓存数据
		 * 
		 * @param key
		 */
		addData : function(key, data) {
			this.data[key] = data;
		},
		/*
		 * 获取缓存content
		 * 
		 * @param key
		 */
		getContent : function(key) {
			return this.content[key];
		},
		/*
		 * 添加缓存数据
		 * 
		 * @param key
		 */
		addContent : function(key, content) {
			this.content[key] = content;
		},
		/*
		 * 添加缓存回调函数
		 * 
		 * @param key
		 */
		addCallBack : function(key, callback) {
			var cb = this.callback[key];
			if (!cb) {
				this.callback[key] = [];
				cb = this.callback[key];
			}
			cb.push(callback);
		},
		/*
		 * 获取缓存回调函数
		 * 
		 * @param key
		 */
		getCallBack : function(key) {
			return this.callback[key];
		},
		/*
		 * 判断是否已经存在缓存
		 * 
		 * @param key
		 */
		isCached : function(key) {
			return this.getData(key) !== undefined && this.getData(key) !== 'caching';
		},
		/*
		 * 判断是否正在缓存中
		 * 
		 * @param key
		 */
		isCaching : function(key) {
			return this.getData(key) === 'caching';
		},
		/*
		 * 设置为正在缓存
		 * 
		 * @param key
		 */
		caching : function(key) {
			this.data[key] = 'caching';
		},
		/*
		 * 判断是否拥有缓存，
		 * 如果存在则执行回调函数
		 * 正在缓存则添加回调函数到缓存中
		 * 否则执行回调函数
		 * 
		 * @param key
		 * @param callback
		 */
		cache : function(key, callback) {
			if (this.isCached(key)) {
				this.call(key, callback);
			} else if (this.isCaching(key)) {
				this.addCallBack(key, callback);
			} else {
				this.addCallBack(key, callback);
				return false;
			}
			return true;
		},
		/*
		 * 根据缓存中的content和数据，执行回调函数
		 * 
		 * @param key
		 * @param callback
		 */
		call : function(key, callback) {
			if ($.isFunction(callback)) {
				callback.apply(this.getContent(key), this.getData(key));
			}
		},
		/*
		 * 根据缓存中的content和数据，执行同一批缓存下的回调函数
		 * 
		 * @param key
		 * @param callback
		 */
		callAll : function(key, data, content) {
			if (data !== undefined && content !== undefined) {
				this.addData(key, data);
				this.addContent(key, content);
			}
			var cb = this.callback[key];
			if (cb) {
				for (var index in cb) {
					cb[index] && cb[index].apply(this.getContent(key), this.getData(key));
				}
			}
			delete this.callback[key];
		}
	};
	/*
	 * 显示信息
	 * 
	 * @param opts
	 * 			1. {String} 提示信息 
	 * 			2. {JSON}
	 * 				msg			: 提示信息内容
	 * 				timeout		: 显示时间
	 * 				position	: 显示位置
	 * 				type		: 提示类别
	 */
	Core.showMsg = function(opts) {
		if (!$.isPlainObject(opts)) {
			opts = {
				msg : opts || '操作成功！'
			};
		}
		opts = $.extend({
			position : {
				at : 'center',
				my : 'center',
				of : 'body'
			},
			timeout : 6000,
			type : 'success'
		}, opts);
		var $box = $('<div class="message-box">');
		$box.append($('<i class="icon-success">')).append(opts.msg);
		$('body').append($box);
		// if (opts.position) {
		$box.position(opts.position);
		// } else if (opts.el) {
		// var $el = $(opts.el);
		// offset = $el.offset();
		// $box.css({
		// left : offset.left,
		// top : offset.top - $el.outerHeight() - 3
		//			});
		//		}
		$box.fadeIn(200, function() {
			$box.fadeOut(opts.timeout, function() {
				$(this).remove();
			});
		});
	};
	if (Backbone) {
		Backbone._sync = Backbone.sync;
		Backbone.sync = function(method, model, options) {
			options = options || {};
			var error = options.error;
			var showError = options.showError === undefined ? true : options.showError;
			options.error = function() {
				if (HZBank.Core.errorHandler && showError) {
					var arrs = [];
					for ( var i = 0; i < arguments.length; i++) {
						arrs.push(arguments[i]);
					}
					arrs.push(options);
					HZBank.Core.errorHandler.apply(this, arrs);
				}
				if (error) {
					error.apply(this, arguments);
				}
			};
			Backbone._sync.apply(this, arguments);
		};
	}
	HZBank.showMsg = Core.showMsg;
	HZBank.ajax = Core.ajax;
	HZBank.logger = Core.logger;
	HZBank.ajaxJSON = Core.ajaxJSON;
	HZBank.loadPage = Core.loadPage;
	this.HZBank = HZBank;
})(this);